import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { LvGutter } from '../core/api';
import { GroupComponent } from './group.component';
import { GroupModule } from './group.module';

@Component({
  template: `
    <lv-group [lvDirection]="lvDirection" [lvGutter]="lvGutter">
      <button lv-button>Item 1</button>
      <button lv-button>Item 2</button>
      <button lv-button disabled>Item 3</button>
    </lv-group>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestGroupBasicComponent {
  @Input() lvDirection: GroupComponent['lvDirection'];
  @Input() lvGutter: LvGutter;

  columnItems = [{}, {}, {}, {}, {}];
}

@Component({
  template: `
    <lv-group
      [lvColumns]="lvColumns"
      [lvRowGutter]="lvRowGutter"
      [lvColumnGutter]="lvColumnGutter"
      [lvWrap]="lvWrap"
    >
      <div *ngFor="let item of columnItems; let i = index">{{ i + 1 }}</div>
    </lv-group>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestGroupMultiComponent {
  @Input() lvColumns: string[] | number[];
  @Input() lvRowGutter: LvGutter;
  @Input() lvColumnGutter: LvGutter;
  @Input() lvWrap: boolean;

  columnItems = [{}, {}, {}, {}, {}];
}

describe('GroupComponent', () => {
  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [TestGroupBasicComponent, TestGroupMultiComponent],
      imports: [GroupModule],
      teardown: { destroyAfterEach: true },
    }).compileComponents();
  }));

  describe('render', () => {
    let component: TestGroupBasicComponent;
    let fixture: ComponentFixture<TestGroupBasicComponent>;
    let cdr: ChangeDetectorRef;

    beforeEach(() => {
      fixture = TestBed.createComponent(TestGroupBasicComponent);
      component = fixture.componentInstance;
      cdr = fixture.debugElement.injector.get(ChangeDetectorRef);
      component.lvDirection = 'horizontal';
      component.lvGutter = '16px';
    });

    it('with default group', () => {
      fixture.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvGutter = 'none';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });

    it('with vertical group', () => {
      component.lvDirection = 'vertical';
      fixture.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvGutter = 'none';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });
  });

  describe('multi columns render', () => {
    let component: TestGroupMultiComponent;
    let fixture: ComponentFixture<TestGroupMultiComponent>;
    let cdr: ChangeDetectorRef;

    beforeEach(() => {
      fixture = TestBed.createComponent(TestGroupMultiComponent);
      component = fixture.componentInstance;
      cdr = fixture.debugElement.injector.get(ChangeDetectorRef);
      component.lvColumns = [];
      component.lvColumnGutter = '15px';
      component.lvRowGutter = '10px';
    });

    it('group of adaptive width should render correctly', () => {
      component.lvColumnGutter = '20px';
      component.lvRowGutter = '20px';
      component.lvColumns = ['auto', 'auto'];
      fixture.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvColumnGutter = 'none';
      component.lvRowGutter = 'none';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });

    it('group of fixed width should render correctly', () => {
      component.lvColumnGutter = '20px';
      component.lvRowGutter = '20px';
      component.lvColumns = ['100px', '200px'];
      fixture.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvColumnGutter = 'none';
      component.lvRowGutter = 'none';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });

    it('group of mixed width should render correctly', () => {
      component.lvColumnGutter = '20px';
      component.lvRowGutter = '20px';
      component.lvColumns = ['100px', 'auto', '20%'];
      fixture.detectChanges();
      expect(fixture).toMatchSnapshot();

      component.lvColumnGutter = 'none';
      component.lvRowGutter = 'none';
      cdr.detectChanges();
      expect(fixture).toMatchSnapshot();
    });
  });
});
